using System;
using System.Runtime.InteropServices;

namespace Leap
{
	public class Device : Interface
	{
		public enum DeviceType
		{
			TYPE_PERIPHERAL = 1,
			TYPE_LAPTOP,
			TYPE_KEYBOARD
		}

		private HandleRef swigCPtr;

		public float HorizontalViewAngle => LeapPINVOKE.Device_HorizontalViewAngle_get(swigCPtr);

		public float VerticalViewAngle => LeapPINVOKE.Device_VerticalViewAngle_get(swigCPtr);

		public float Range => LeapPINVOKE.Device_Range_get(swigCPtr);

		public float Baseline => LeapPINVOKE.Device_Baseline_get(swigCPtr);

		public bool IsValid => LeapPINVOKE.Device_IsValid_get(swigCPtr);

		public bool IsEmbedded => LeapPINVOKE.Device_IsEmbedded_get(swigCPtr);

		public bool IsStreaming => LeapPINVOKE.Device_IsStreaming_get(swigCPtr);

		public bool IsFlipped => LeapPINVOKE.Device_IsFlipped_get(swigCPtr);

		public DeviceType Type => (DeviceType)LeapPINVOKE.Device_Type_get(swigCPtr);

		public string SerialNumber => LeapPINVOKE.Device_SerialNumber_get(swigCPtr);

		public Vector Position
		{
			get
			{
				IntPtr intPtr = LeapPINVOKE.Device_Position_get(swigCPtr);
				return (intPtr == IntPtr.Zero) ? null : new Vector(intPtr, true);
			}
		}

		public Matrix Orientation
		{
			get
			{
				IntPtr intPtr = LeapPINVOKE.Device_Orientation_get(swigCPtr);
				return (intPtr == IntPtr.Zero) ? null : new Matrix(intPtr, true);
			}
		}

		public static Device Invalid => new Device(LeapPINVOKE.Device_Invalid_get(), false);

		public Device(IntPtr cPtr, bool cMemoryOwn)
			: base(LeapPINVOKE.Device_SWIGUpcast(cPtr), cMemoryOwn)
		{
			swigCPtr = new HandleRef(this, cPtr);
		}

		public static HandleRef getCPtr(Device obj)
		{
			return obj?.swigCPtr ?? new HandleRef(null, IntPtr.Zero);
		}

		~Device()
		{
			Dispose();
		}

		public override void Dispose()
		{
			lock (this)
			{
				if (swigCPtr.Handle != IntPtr.Zero)
				{
					if (base.swigCMemOwn)
					{
						base.swigCMemOwn = false;
						LeapPINVOKE.delete_Device(swigCPtr);
					}
					swigCPtr = new HandleRef(null, IntPtr.Zero);
				}
				GC.SuppressFinalize(this);
				base.Dispose();
			}
		}

		public Device()
			: this(LeapPINVOKE.new_Device(), true)
		{
		}

		public float DistanceToBoundary(Vector position)
		{
			float result = LeapPINVOKE.Device_DistanceToBoundary(swigCPtr, Vector.getCPtr(position));
			if (LeapPINVOKE.SWIGPendingException.Pending)
			{
				throw LeapPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public bool Equals(Device arg0)
		{
			bool result = LeapPINVOKE.Device_Equals(swigCPtr, getCPtr(arg0));
			if (LeapPINVOKE.SWIGPendingException.Pending)
			{
				throw LeapPINVOKE.SWIGPendingException.Retrieve();
			}
			return result;
		}

		public override string ToString()
		{
			return LeapPINVOKE.Device_ToString(swigCPtr);
		}
	}
}
